package de.breitbeil.jbooking.task;

import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.breitbeil.jbooking.domain.Booking;
import de.breitbeil.jbooking.domain.Person;
import de.breitbeil.jbooking.ui.form.BookingTemplateFormObject;

public class BookingTemplateTask extends AbstractTask<Void, Void> {
    
	private Log logger = LogFactory.getLog(getClass());
	
    private BookingTemplateFormObject config;
    private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
    private DecimalFormat priceFormat = new DecimalFormat("#0.00");
    
    public BookingTemplateTask(BookingTemplateFormObject config) {
        super("bookingTemplateTask");
        
        this.config = config;
    }
    
    @Override
    protected Void doInBackground() throws Exception {
        
        String rtfSource = config.getTemplate();
        String rtfTarget = config.getOutput();
        if(!rtfTarget.toUpperCase().endsWith(".RTF")) {
        	rtfTarget = rtfTarget + ".rtf";
        }
         
        HashMap<String, Object> context =  new HashMap<String, Object>();
        
        Person person = config.getPerson();
        context.put("<person_id>", getStringValue(person.getId()));
        context.put("<person_lastname>", getStringValue(person.getLastname()) );
        context.put("<person_firstname>", getStringValue(person.getFirstname()) );
        context.put("<person_address1>", getStringValue(person.getAddress1()) );
        context.put("<person_address2>", getStringValue(person.getAddress2()) );
        context.put("<person_address3>", getStringValue(person.getAddress3()) );
        context.put("<person_zip>", getStringValue(person.getZip()) );
        context.put("<person_city>", getStringValue(person.getCity()) );
        context.put("<person_email>", getStringValue(person.getEmail()) );
        context.put("<person_homephone>", getStringValue(person.getHomePhone()) );
        context.put("<person_workphone>", getStringValue(person.getWorkPhone()) );
        
        context.put("<person_address>", getStringValue(person.getAddress()) );
        context.put("<person_address0>", getStringValue(person.getAddress0()) );
        context.put("<person_mobil>", getStringValue(person.getMobil()) );

        context.put("<person_p_lastname>", getStringValue(person.getP_lastname()) );
        context.put("<person_p_firstname>", getStringValue(person.getP_firstname()) );
        

        context.put("<person_birthday>", getDateValue(person.getBirthday()) );
        context.put("<person_p_birthday>", getDateValue(person.getP_birthday()) );
        
        //context.put("<description>", person.getDescription());
        
        Booking booking = config.getBooking();
        if(booking != null) {
            context.put("<booking_id>", getStringValue(booking.getId()));
	        context.put("<booking_date>", getDateValue(booking.getBookingDate()) );
	        context.put("<booking_from>", getDateValue(booking.getFrom()) );
	        context.put("<booking_to>", getDateValue(booking.getTo()) );
	        context.put("<booking_numDays>", getStringValue(booking.getNumDays()) );
	        context.put("<booking_adults>", getStringValue(booking.getNumberAdults()) );
	        context.put("<booking_children>", getStringValue(booking.getNumberChildren()) );
	        context.put("<booking_dogs>", getStringValue(booking.getNumberDogs()) );
	        
	        Double prepayment = getDoubleValue(booking.getPrepayment());
	        Double price = getDoubleValue(booking.getPrice());
	        Double vtax = getDoubleValue(booking.getVtax());
	        // Double completePrice = prepayment + price;
	        Double completePrice = price + vtax;
	        Double balance = price + vtax - prepayment;
	        
	        context.put("<booking_prepayment>", priceFormat.format(prepayment));
	        context.put("<booking_price>", priceFormat.format(price));
	        context.put("<booking_complete_price>", priceFormat.format(completePrice));
	        context.put("<booking_balance>", priceFormat.format(balance));
	        context.put("<booking_vtax>", priceFormat.format(vtax));
	        context.put("<booking_vtax_no>", getStringValue(booking.getVtax_no()) );
        }
        
        String buffer;
        
        BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(rtfSource)), 1000) ;
        
        FileOutputStream fileoutput = new FileOutputStream(rtfTarget) ;
        DataOutput outFile = new DataOutputStream(fileoutput ) ;

        while (input.ready()) {
            buffer = input.readLine();

            for(String key: context.keySet()) {
                Object value = (context.get(key));
                String valueString = (value == null)? "" : value.toString();
                buffer = buffer.replaceAll(key, valueString) ;
            }

            outFile.writeBytes(buffer +"\n");  // weiss nicht, ob "\n" noetig ist
        }
        input.close();
        fileoutput.close();
        
        // Edit file if specified
        logger.info("Open file? "+config.isOpenOutput());
        if(config.isOpenOutput()) {
        	Desktop desktop = Desktop.getDesktop();
        	logger.info("If open action is supported... ");
            if(desktop.isSupported(Desktop.Action.OPEN)) {
            	logger.info(" opening file.");
            	desktop.open(new File(rtfTarget));
            }
        }
        
        return null;
    }
    
    private String getStringValue(Object o) {
    	return (o == null)? "" : o.toString(); 
    }
    
    private String getDateValue(Date date) {
    	return (date == null)? "" : sdf.format(date);
    }
    
    private Double getDoubleValue(Double d) {
    	return (d == null)? 0 : d;
    }

}
